import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
import socket
import threading

class SocketClientGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("Socket客户端")
        self.root.geometry("600x500")
        
        # Socket相关变量
        self.client_socket = None
        self.connected = False
        
        self.setup_ui()
        
    def setup_ui(self):
        # 主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 连接设置区域
        connect_frame = ttk.LabelFrame(main_frame, text="连接设置", padding="10")
        connect_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        ttk.Label(connect_frame, text="服务器地址:").grid(row=0, column=0, sticky=tk.W, padx=(0, 5))
        self.host_entry = ttk.Entry(connect_frame, width=20)
        self.host_entry.insert(0, "localhost")
        self.host_entry.grid(row=0, column=1, padx=(0, 10))
        
        ttk.Label(connect_frame, text="端口:").grid(row=0, column=2, sticky=tk.W, padx=(0, 5))
        self.port_entry = ttk.Entry(connect_frame, width=10)
        self.port_entry.insert(0, "12345")
        self.port_entry.grid(row=0, column=3, padx=(0, 10))
        
        self.connect_btn = ttk.Button(connect_frame, text="连接", command=self.connect_server)
        self.connect_btn.grid(row=0, column=4, padx=(0, 5))
        
        self.disconnect_btn = ttk.Button(connect_frame, text="断开", command=self.disconnect, state=tk.DISABLED)
        self.disconnect_btn.grid(row=0, column=5)
        
        # 消息显示区域
        message_frame = ttk.LabelFrame(main_frame, text="消息记录", padding="10")
        message_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10))
        
        self.message_text = scrolledtext.ScrolledText(message_frame, height=15, width=70)
        self.message_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 消息发送区域
        send_frame = ttk.LabelFrame(main_frame, text="发送消息", padding="10")
        send_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E))
        
        ttk.Label(send_frame, text="消息:").grid(row=0, column=0, sticky=tk.W, padx=(0, 5))
        self.send_entry = ttk.Entry(send_frame, width=50)
        self.send_entry.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=(0, 10))
        self.send_entry.bind('<Return>', self.send_message_enter)
        
        self.send_btn = ttk.Button(send_frame, text="发送", command=self.send_message, state=tk.DISABLED)
        self.send_btn.grid(row=0, column=2)
        
        # 配置网格权重
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.columnconfigure(1, weight=1)
        main_frame.rowconfigure(1, weight=1)
        message_frame.columnconfigure(0, weight=1)
        message_frame.rowconfigure(0, weight=1)
        send_frame.columnconfigure(1, weight=1)
        
    def connect_server(self):
        if not self.connected:
            try:
                host = self.host_entry.get().strip()
                port = int(self.port_entry.get().strip())
                
                self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.client_socket.connect((host, port))
                self.connected = True
                
                self.connect_btn.config(state=tk.DISABLED)
                self.disconnect_btn.config(state=tk.NORMAL)
                self.send_btn.config(state=tk.NORMAL)
                
                self.add_message(f"已连接到 {host}:{port}")
                
                # 启动接收消息线程
                self.receive_thread = threading.Thread(target=self.receive_messages)
                self.receive_thread.daemon = True
                self.receive_thread.start()
                
            except Exception as e:
                messagebox.showerror("连接错误", f"连接失败: {e}")
                self.add_message(f"连接失败: {e}")
    
    def disconnect(self):
        if self.connected:
            try:
                self.client_socket.close()
                self.connected = False
                
                self.connect_btn.config(state=tk.NORMAL)
                self.disconnect_btn.config(state=tk.DISABLED)
                self.send_btn.config(state=tk.DISABLED)
                
                self.add_message("已断开连接")
            except Exception as e:
                self.add_message(f"断开连接失败: {e}")
    
    def send_message(self):
        if self.connected and self.send_entry.get().strip():
            try:
                message = self.send_entry.get().strip()
                self.client_socket.send(message.encode('utf-8'))
                self.add_message(f"我: {message}")
                self.send_entry.delete(0, tk.END)
            except Exception as e:
                self.add_message(f"发送失败: {e}")
                messagebox.showerror("发送错误", f"发送失败: {e}")
    
    def send_message_enter(self, event):
        self.send_message()
    
    def receive_messages(self):
        while self.connected:
            try:
                data = self.client_socket.recv(1024)
                if not data:
                    break
                message = data.decode('utf-8')
                self.add_message(f"服务器: {message}")
            except Exception as e:
                if self.connected:
                    self.add_message(f"接收消息错误: {e}")
                break
    
    def add_message(self, message):
        self.message_text.insert(tk.END, f"{message}\n")
        self.message_text.see(tk.END)
        self.message_text.update()

def main():
    root = tk.Tk()
    app = SocketClientGUI(root)
    root.mainloop()

if __name__ == "__main__":
    main()